package com.cjm.one.payment.service.impl;

import com.alibaba.fastjson2.JSONObject;
import com.alipay.api.AlipayApiException;
import com.alipay.api.AlipayClient;
import com.alipay.api.DefaultAlipayClient;
import com.alipay.api.internal.util.AlipaySignature;
import com.alipay.api.internal.util.StringUtils;
import com.alipay.api.request.AlipayTradePagePayRequest;
import com.alipay.api.request.AlipayTradeRefundRequest;
import com.alipay.api.response.AlipayTradeRefundResponse;
import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
import com.cjm.one.common.constant.SecurityConstants;
import com.cjm.one.model.order.entity.OrderInfo;
import com.cjm.one.model.order.enums.OrderStatusEnum;
import com.cjm.one.model.order.vo.OrderInfoVo;
import com.cjm.one.model.payment.entity.AliPay;
import com.cjm.one.model.payment.entity.PaymentInfo;

import com.cjm.one.order.client.OrderInfoClient;
import com.cjm.one.payment.config.AlipayConfig;
import com.cjm.one.payment.mapper.PaymentInfoMapper;
import com.cjm.one.payment.service.PaymentInfoService;
import jakarta.annotation.Resource;
import jakarta.servlet.http.HttpServletRequest;
import jakarta.servlet.http.HttpServletResponse;
import lombok.extern.slf4j.Slf4j;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;

import java.io.IOException;
import java.text.ParseException;
import java.text.SimpleDateFormat;
import java.time.LocalDateTime;
import java.util.Date;
import java.util.HashMap;
import java.util.Map;
import java.util.UUID;

/**
* @author 29289
* @description 针对表【payment_info(付款信息表)】的数据库操作Service实现
* @createDate 2024-09-05 16:27:50
*/
@Service
@Slf4j
public class PaymentInfoServiceImpl extends ServiceImpl<PaymentInfoMapper, PaymentInfo>
    implements PaymentInfoService {

    private static final String FORMAT = "JSON";
    private static final String CHARSET = "UTF-8";

    private  static  final  String paymentMethod = "支付宝支付";

    @Resource
    private AlipayConfig aliPayConfig;

    @Resource
    private OrderInfoClient orderInfoClient;



    @Override
    @Transactional
    public Boolean processRefund(AliPay aliPay) throws AlipayApiException {
        log.info("退款：{}",aliPay);
        OrderInfo orders = orderInfoClient.getByorderNo(aliPay.getTraceNo(),SecurityConstants.INNER).getData();
        if(orders == null) {
            return false;
        }
        // 1. 创建Client，通用SDK提供的Client，负责调用支付宝的API
        AlipayClient alipayClient = new DefaultAlipayClient(aliPayConfig.getGatewayUrl(),
                aliPayConfig.getAppId(), aliPayConfig.getMerchantPrivateKey(), FORMAT, CHARSET,
                aliPayConfig.getAlipayPublicKey(), aliPayConfig.getSignType());
        // 2. 创建 Request，设置参数
        AlipayTradeRefundRequest request = new AlipayTradeRefundRequest();
        // TODO:未写入部分退款时的操作记录
        String outRequestNo = UUID.randomUUID().toString().replace("-", "");
        // 使用JSONObject构建参数
        log.info("bizContent-aliPay:{}",aliPay);
        JSONObject bizContent = new JSONObject();
        bizContent.put("out_trade_no", orders.getOrderNo()); // 商户订单号 我的订单编号
        bizContent.put("trade_no", orders.getTradeNo()); // 支付宝交易号 支付宝回调的订单流水号
        bizContent.put("refund_amount", String.format("%.2f", orders.getTotalAmount())); // 格式化金额 订单的总金额
        bizContent.put("out_request_no", outRequestNo);   //这个参数需要注意，如果想要实现部分退款逻辑这个参数是必须的
        request.setBizContent(bizContent.toString());
        // 返回参数选项，按需传入
        //JSONArray queryOptions = new JSONArray();
        //queryOptions.add("refund_detail_item_list");
        //bizContent.put("query_options", queryOptions);

        // 3. 执行请求
        AlipayTradeRefundResponse response = alipayClient.execute(request);
        if (response.isSuccess()) {  // 退款成功，isSuccess 为true
            System.out.println("调用成功");
            // 4. 更新数据库状态
            orders.setOrderStatus(OrderStatusEnum.REFUNDED);
            orders.setRefundTime(LocalDateTime.now());
            orders.setRefundAmount(aliPay.getTotalAmount());
            log.info("退款成功，订单号：{}，金额：{}",
                    orders.getOrderNo(), orders.getRefundAmount());
            return orderInfoClient.updateOrder(orders,SecurityConstants.INNER).getData();

        } else {   // 退款失败，isSuccess 为false
        log.info("退款失败，订单编号：{}，金额：{}",orders.getOrderNo(), orders.getTotalAmount());
            return response.isSuccess();
        }
    }

    @Override
    @Transactional
    public String pay(String orderNo ,HttpServletResponse httpResponse) throws IOException {
        OrderInfoVo orderInfo = orderInfoClient.getByorderNo(orderNo, SecurityConstants.INNER).getData();
        log.info("支付");
        log.info("orderInfo支付：" + orderInfo);
        if (orderInfo == null) {
            return "";
        }
        // 1. 创建Client，通用SDK提供的Client，负责调用支付宝的API
        AlipayClient alipayClient = new DefaultAlipayClient(aliPayConfig.getGatewayUrl(), aliPayConfig.getAppId(),
                aliPayConfig.getMerchantPrivateKey(), FORMAT, CHARSET, aliPayConfig.getAlipayPublicKey(), aliPayConfig.getSignType());

        // 2. 创建 Request并设置Request参数
        AlipayTradePagePayRequest request = new AlipayTradePagePayRequest();  // 发送请求的 Request类
        request.setNotifyUrl(aliPayConfig.getNotifyUrl());
//        sk-a94d5461579c4893b6c4a72aa5de02d8
        request.setBizContent(
                " {\"out_trade_no\":\"" + orderInfo.getOrderNo() + "\","
                        + "\"total_amount\":\"" + orderInfo.getTotalAmount() + "\","
                        + "\"subject\":\"" + orderInfo.getId() + orderInfo.getNickName()
                        + "\","
                        + "\"body\":\"" + paymentMethod + "\","
                        +
                        "\"timeout_express\":\"" + aliPayConfig.getTimeout() + "\","
                        +
                        "\"product_code\":\"FAST_INSTANT_TRADE_PAY\"}"

        );
        request.setReturnUrl("http://localhost:9000/unibest/#/pages/pay/paySuccess?orderId="+orderInfo.getId()); // 支付完成后自动跳转到本地页面的路径
        // 执行请求，拿到响应的结果，返回给浏览器
        String form = "";
        try {
            form = alipayClient.pageExecute(request).getBody(); // 调用SDK生成表单

        } catch (AlipayApiException e) {
            e.printStackTrace();
        }
        return form;

    }

    @Override
    @Transactional
    public String notify(Map<String, String> params) throws ParseException, AlipayApiException {
        if (params.get("trade_status").equals("TRADE_SUCCESS")) {
            System.out.println("=========支付宝异步回调========");



            String tradeStatus = params.get("trade_status");
            String sign = params.get("sign");
            log.info("支付宝回调参数tradeStatus：" + tradeStatus);
            String content = AlipaySignature.getSignCheckContentV1(params);
            boolean checkSignature = AlipaySignature.rsa256CheckContent(content, sign, aliPayConfig.getAlipayPublicKey(), "UTF-8"); // 验证签名

            // 支付宝验签
            if (checkSignature) {
                // 验签通过
                System.out.println("交易名称: " + params.get("subject"));
                System.out.println("交易状态: " + params.get("trade_status"));
                System.out.println("支付宝交易凭证号: " + params.get("trade_no"));
                log.info("支付宝回调参数params：" + params);
                log.info("支付宝回调参数trade_status：" + params.get("trade_status"));
                System.out.println("商户订单号: " + params.get("out_trade_no"));
                System.out.println("交易金额: " + params.get("total_amount"));
                System.out.println("买家在支付宝唯一id: " + params.get("buyer_id"));
                System.out.println("买家付款时间: " + params.get("gmt_payment"));
                System.out.println("买家付款金额: " + params.get("buyer_pay_amount"));

                String tradeNo = params.get("out_trade_no");//订单编号
                String gmtPayment = params.get("gmt_payment");//支付时间
                String alipayTradeNo = params.get("trade_no");//支付宝交易编号 流水号


                // 更新订单状态为待发货，设置支付信息
                OrderInfo orders = orderInfoClient.getByorderNo(tradeNo,SecurityConstants.INNER).getData();

                // 区分支付和退款场景
                if (isRefundNotification(params)) {
                    // 处理退款回调

                } else if ("TRADE_SUCCESS".equals(tradeStatus)) {
                    // 处理支付成功回调
                    //支付宝订单流水号
                    orders.setTradeNo(alipayTradeNo);
                    // 更新订单状态为已支付，设置支付信息
                    orders.setOrderStatus(OrderStatusEnum.WAIT_DELIVER);


                    orders.setPaymentTime(LocalDateTime.now());
                    orderInfoClient.updateOrder(orders,SecurityConstants.INNER);
                }
//

            }

        }
        return "success";
    }
    // 判断是否为退款通知
    private boolean isRefundNotification(Map<String, String> params) {
        return params.containsKey("refund_fee")
                && !StringUtils.isEmpty(params.get("refund_fee"));
    }
}




